#ifndef _HTTP_H_
#define _HTTP_H_

#include "protocol.h"
#include "queue.h"
#include <limits.h>

/********************************************************
 * definienss
 *******************************************************/
 
#ifndef IOV_MAX
#define IOV_MAX 1024
#endif


#define MAX_PATCH_NUMBER	IOV_MAX

#define REQUEST_URL_MAX_LENGTH          1024    /* length limit of request url */
#define REQUEST_HEADER_BUF_MAX_LENGTH   81920   /* match csf configuration, do not modify */
#define RESPONSE_BUF_MAX_LENGTH         1024    /* response buffer */
#define RESPONSE_FILE_BUF_LENGTH        10240   /* response buffer */
#define MAX_HEADER_FIELDS               17      /* length of hash table */
#define SITE_ROOT_DIR_LENGTH            200     /* length of SITE_ROOT_DIR */
#define UPLOAD_BUF_SIZE                 262144  /* upload buf 256KB */
#define SITE_DEFAULT_PAGE       "index.htm","index.html","default.htm","default.html" 

/* http flow state control */
#define HTTP_FLOW_CONTINUE      0
#define HTTP_PIPE_LINE_STOP     1
#define HTTP_PROTOCOL_STOP      2
#define HTTP_PIPE_LINE_DONE     3


/* index <-> fieldname mapping 
 * the count of this list must match MAX_HEADER_FIELDS */
#define METHOD              0
#define URI                 1
#define PROTOCOL            2
#define AUTHORIZATION       3
#define FROM                4
#define IF_MODIFIED_SINCE   5
#define REFERER             6
#define USER_AGENT          7
#define HOST                8
#define PRAGMA              9
#define ALLOW               10
#define CONTENT_ENCODING    11
#define CONTENT_LENGTH      12
#define CONTENT_TYPE        13
#define EXPIRES             14
#define LAST_MODIFIED       15
#define ENTITY              16

int MAX_POST_BYTES;

//#define DEBUG         /* whether print debug message on screen */
//#define UPLOAD_DEBUG
//#define MALLOC_DEBUG
//#define LOGGING       /* switch off some inessential log(more log worse performance) */
//#define SHOW_UPLOAD_PROGRESS    /* show UPLOAD_PROGRESS in csf terminal */

#define FREEBSD     0   /* freeBSD sendfile system call */
#define LINUX       1   /* linux sendfile system call */
#define COMMON      2   /* common read & write system call */

/* indicates which method to be used to response a file */
#define HOW_TO_RESPONSE_FILE    FREEBSD

/********************************************************
 * my own data structs
 *******************************************************/

/* the STAIQ_LIST's head pointor type */
typedef STAILQ_HEAD(hd, entry)STQ_HEAD;

/* head fields prototype */
typedef struct header_fields
{
    const char *field_name;
    char *field_value;
}HEADER_FIELD;


/* the node struct of upload data list */
struct entry		
{
	char buf[UPLOAD_BUF_SIZE + 1];
	size_t len;
	STAILQ_ENTRY(entry) entries;
};

typedef struct entry UPLOAD_PATCH;

/* http request data */
typedef struct http_request_data
{
    int request_fd;             /* the file descriptor of socket */
    char *request_data;         /* the full request string */
    char *request_data_backup; 
    char upload_buf[UPLOAD_BUF_SIZE + 1];
    ssize_t upload_buf_len;
    char is_entity_exist;       
    char is_header_processed;
    char is_to_submit;
    char is_submitted;
    char state;
    ssize_t request_entity_len;
    ssize_t request_entity_sent_bytes;
    ssize_t request_len;        /* length of request data */
    HEADER_FIELD *header_field_ptr;
    CONN_INFO *cip;             /* csf cip struct */
    STQ_HEAD patch_head;
}HTTP_REQUEST;


/********************************************************
 * global function declarations
 *******************************************************/
 
/* http_serve_funcs.c */
void urldecode(char *buf);
void swapchar(char *string, char oldchar, char newchar);
char *get_header_field_value(HEADER_FIELD *header_field, char *key);
void set_header_field_value(HEADER_FIELD *header_field, char *key, char *value);
char *trim(char *src);
char *bsd_strnstr(const char *s, const char *find, size_t slen);

/* http_request.c */
int parse_http_request(HTTP_REQUEST *req_info);
                       

#endif



